package com.vip.sys.modular.login.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.vip.sys.modular.resources.entity.Resources;
import com.vip.sys.modular.user.entity.SecurityUser;
import com.vip.sys.modular.user.entity.User;
import com.vip.sys.modular.user.service.UserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用于认证
 * @author tianlianyin
 * @Date 2024/11/17
 */
@Service
@Slf4j
@Transactional//事务注解，保证事务的一致性<NEWLINE>public
public class SecurityUserDetailImpl implements UserDetailsService {
    @Resource
    private UserService userService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        User user = userService.getOne(wrapper);
        if (user != null) {
            SecurityUser securityUser = new SecurityUser();
            securityUser.setUserId(user.getId());
            securityUser.setUsername(user.getUsername());
            securityUser.setPassword(user.getPassword());
            securityUser.setAuthorities(getUserAuthority(username));
            return securityUser;
        }
        return null;
    }
    /**
     * 获取用户权限信息（角色、菜单权限）
     * @param username 用户名
     * @return 权限列表
     */
    public List<GrantedAuthority> getUserAuthority(String username) {
        // 角色(比如ROLE_admin)，菜单操作权限(比如sys:user:list)
        // 角色必须以ROLE_开头，security在判断角色时会自动截取ROLE_
        List<Resources> permissions = userService.getAllAuthByName(username);
        // 比如ROLE_admin,ROLE_normal,sys:user:list,...
        String authority = "";
        if (CollectionUtils.isNotEmpty(permissions)) {
            List<String> urls = permissions.stream().map(Resources::getAuthFlag).collect(Collectors.toList());
            authority = StrUtil.join(",", urls);
        }
        return AuthorityUtils.commaSeparatedStringToAuthorityList(authority);
    }
}
